package com.hoongs.v1.service;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hoongs.v1.utils.JwtUtil;
import com.hoongs.v1.utils.Result;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;

import static com.hoongs.v1.utils.DateUtil.formatTime;

@Service
public class FileService {

    @Value("${fileOptions.savePath}")
    private String basePath;

    @Value("${fileOptions.allowTypes}")
    private String[] fileTypes;

    public Map<String, String> saveFile(MultipartFile file) throws IOException {
        Map<String, String> resultMap = new HashMap<>();
        if (file.isEmpty()) {
            resultMap.put("errorMsg", "上传文件不存在！");
            return resultMap;
        }
        String dateStr = formatTime(Calendar.getInstance().getTime(), "YYYYMM");
        // 生成文件目录
        String uploadPath = basePath + dateStr;
        // 如果文件目录不存在则创建
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) uploadDir.mkdir();

        //获取原文件名
        String OriginalFilename = file.getOriginalFilename();
        resultMap.put("originalName", OriginalFilename);
        //获取文件后缀名
        String suffixName = OriginalFilename.substring(OriginalFilename.lastIndexOf("."));
        List<String> fileTypeList = Arrays.asList(fileTypes);
        // 判断是否是允许的文件类型
        if (!fileTypeList.contains(suffixName)) {
            resultMap.put("errorMsg", "只能上传" + fileTypeList.toString() + "文件！");
            return resultMap;
        }

        // 重新随机生成名字
        String newFileName = JwtUtil.getUUID() + suffixName;
        String contextPath = uploadPath + "/" + newFileName;

        File localFile = new File(contextPath);
        // 如果
        if (".png".equals(suffixName)) {
            localFile = ConvertImageFile(localFile);
        }
        // 设置文件访问权限
        localFile.setWritable(true, false);
        localFile.setReadable(true, false);
        localFile.setExecutable(true, false);
        BufferedImage image = ImageIO.read(file.getInputStream());

        try {
            file.transferTo(localFile); //把上传的原文件保存至本地

            if (".jpg".equals(suffixName)) {
                if (image.getHeight() > 360 || image.getWidth() > 360) {
                    Thumbnails.of(contextPath).size(image.getWidth() / 3, image.getHeight() / 3).outputQuality(1f).toFile(contextPath.replace(".", "_thumb."));
                }
            }
            /**
             * 这里应该把filename保存到数据库,供前端访问时使用
             */
            resultMap.put("name", newFileName);
            resultMap.put("url", dateStr + "/" + newFileName);
            resultMap.put("url_thumb", dateStr + "/" + newFileName.replace(".", "_thumb."));
            resultMap.put("successMsg", "文件上传成功");
            return resultMap;//上传成功，返回保存的文件地址
        } catch (IOException e) {
            e.printStackTrace();
            resultMap.put("uploadFileDir", contextPath);
            resultMap.put("errorMsg", "文件上传失败");
            resultMap.put("errorRemark", e.getMessage());
            return resultMap;
        }
    }

    /**
     * 单文件上传
     *
     * @param file
     * @return
     */
    public Result fileUpload(MultipartFile file) throws IOException {
        Map<String, String> map = this.saveFile(file);
        if (StringUtils.isNotBlank(map.get("errorMsg"))) {
            return Result.opError(map.get("errorMsg"));
        } else {
            return Result.opSuccess("文件上传成功！", map);
        }
    }

    /**
     * 多文件上传
     *
     * @param files
     * @return
     */
    public Result filesUpload(MultipartFile[] files) throws IOException {
        List list = new ArrayList<>();
        for (MultipartFile fileItem : files) {
            Map<String, String> map = this.saveFile(fileItem);
            list.add(map);
        }
        if (list.size() > 0) {
            return Result.opSuccess("上传完成！", list);
        } else {
            return Result.opError("上传失败！");
        }
    }

    /**
     * 将图片格式由png转为jpg
     */
    public File ConvertImageFile(File file) {
        try {
            BufferedImage inImage = ImageIO.read(file);
            BufferedImage outImage = new BufferedImage(inImage.getWidth(),
                    inImage.getHeight(), BufferedImage.TYPE_INT_RGB);
            //由于png格式是32位，jpg格式是24位，因此要进行位数转换
            //TYPE_INT_RGB:创建一个RBG图像，24位深度，成功将32位图转化成24位
            outImage.createGraphics().drawImage(inImage, 0, 0, Color.WHITE, null);
            File outFile = new File(file.getName() + ".jpg");
            ImageIO.write(outImage, "jpg", outFile);
            return outFile;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}
